package com.dycong.common.web;

import lombok.extern.log4j.Log4j2;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Log4j2
@ControllerAdvice
public class GlobalExceptionHandler {
    // TODO: 2019/6/22 在 ControllerAdvice 中定义多个@ExceptionHandler 处理不同的异常 ，Order 对 ExceptionHandler 顺序无效，ExceptionHandlerMethodResolver
    //  会对异常的匹配程度进行排序，取匹配度最高的resolveMethod处理异常
    @ResponseBody
    @ExceptionHandler({Exception.class, ConstraintViolationException.class})
    public JSONResult<String> handleApiConstraintViolationException(Exception ex) {
        String message = ex.getMessage();
        try {
            if (ex instanceof ConstraintViolationException) {
                Set<ConstraintViolation<?>> violations = ((ConstraintViolationException) ex).getConstraintViolations();
                message = violations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(","));
            } else if (ex instanceof BindException) {
                List<ObjectError> violations = ((BindException) ex).getBindingResult().getAllErrors();
                message = violations.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(","));
            }
        }catch (Exception e){
            log.error("Validated GlobalExceptionHandler", e);
        }
        return new JSONResult<>(-2, "参数错误", message);
    }

//    @Order(10) todo Order 对 ExceptionHandler 顺序无效
    @ResponseBody
    @ExceptionHandler({Exception.class})
    public JSONResult<String> handleException(Exception ex) {
        String message = ex.getMessage();
        return new JSONResult<>(-1, "参数错误", message);
    }

    @ResponseBody
    @ExceptionHandler({ArrayIndexOutOfBoundsException.class})
    public JSONResult<String> handleArrayIndexOutOfBoundsException(Exception ex) {
        String message = ex.getMessage();
        return new JSONResult<>(-1, "参数错误", message);
    }

}
